/* Copyright 2012 Dustin Mitchell <dmmitche [at] gmail [dot] com>
 *
 * Licensed under the GPLv3.  See included LICENSE.txt for full details.
 */

#include <string.h>

#include "sensor.h"
#include "gps_sensor.h"
#include "wake_up_sensor.h"
#include "log.h"

int sensor_base_create (struct sensor_base *base, enum sensor_type type,
                        struct sensor_ops *ops)
{
  if (!base || !ops) {
    log (LOG_ERR, "invalid param");
    return -1;
  }

  base->type = type;
  memcpy (&base->ops, ops, sizeof (struct sensor_ops));

  return 0;
}



int sensor_create (union sensor *sensor, union sensor_def *def)
{
  if (!sensor || !def) {
    log (LOG_ERR, "invalid param");
    return -1;
  }

  switch (def->type) {
    case SENSOR_GPS:
      return gps_sensor_create (&sensor->gps, def->gps.hw_uart,
                                def->gps.baud);

    case SENSOR_WAKE_UP:
      return wake_up_sensor_create (&sensor->wake_up, def->wake_up.period_ms);

    /* default purposly left off so compiler will error when a sensor type is
     * forgotten */
  }

  return 0;
}

void sensor_destroy (union sensor *sensor)
{
  if (!sensor) {
    log (LOG_ERR, "invalid param");
    return;
  }

  switch (sensor->sensor.type) {
    case SENSOR_GPS:
      gps_sensor_destroy (&sensor->gps);
      break;

    case SENSOR_WAKE_UP:
      return wake_up_sensor_destroy (&sensor->wake_up);

    /* default purposly left off so compiler will error when a sensor type is
     * forgotten */
  }

  return;
}

int sensor_read (union sensor *sensor, union sensor_reading *reading)
{
  if (!sensor || !reading) {
    log (LOG_ERR, "invalid param");
    return -1;
  }

  if (sensor->sensor.ops.read)
    return sensor->sensor.ops.read (sensor, reading);

  return -1;
}

int sensor_get_selectable (union sensor *sensor)
{
  if (!sensor) {
    log (LOG_ERR, "invalid param");
    return -1;
  }

  if (sensor->sensor.ops.get_selectable)
    return sensor->sensor.ops.get_selectable (sensor);

  return -1;
}
